---
title: useStore Hook
---

import FeedbackRating from '../../components/feedback-rating';

# useStore Hook

Use the `useStore` hook to subscribe to changes for any part of the store.

It returns an array containing two values
 1. `property` value itself.
 2. `setProperty` function, to update the value. It accepts a value or a function.

You can use `useStore` to give an initial value to a property and also define a onAfterUpdate listener.

```jsx
const { useStore } = createStore({ count: undefined });

function onAfterUpdate({ store, prevStore }) {
  console.log(`Count changed from ${prevStore.count} to ${store.count}`);
}

function Counter() {
  const [count, setCount] = useStore.count(0, onAfterUpdate);

  const resetCount = () => {
    setCount(0);
  };
  
  return (
    <div>
      <button onClick={() => setCount((c) => c - 1)}>
        Increase Count
      </button>
      <button onClick={() => setCount((c) => c - 1)}>
        Decrease Count
      </button>
      <button onClick={() => setCount(Math.random() * 100)}>
        Set to Random
      </button>
      <button onClick={resetCount}>
        Reset Count
      </button>
    </div>
  )
}
```

It's recommended to use the useStore hook as a proxy to indicate exactly what portion of the store you want.

This way you only subscribe to this part of the store avoiding unnecessary re-renders.

```jsx
import createStore from 'teaful';

const { useStore } = createStore({
  username: 'Max',
  age: 22,
  cart: {
    price: 0,
    items: [],
  },
});

function Example() {
  // subscribes to changes for the `username` portion of the store
  const [username, setUsername] = useStore.username();
  // subscribes to changes for the `cart.price` portion of the store
  // won't re-render if the `cart.items` changes
  const [cartPrice, setCartPrice] = useStore.cart.price();

  // to see if and when the component re-renders
  console.log('This component re-redered');

  return (
    <>
      <button onClick={() => setUsername('Lando')}>
        Update {username}
      </button>
      <button onClick={() => setCartPrice((v) => v + 1)}>
        Increment price: 💵 {cartPrice}
      </button>
    </>
  );
}
```


However, it's also possible to use the useStore hook to access the store as a whole.

import Callout from 'nextra-theme-docs/callout';

<Callout type="warning" emoji="⚠️">
  This will cause a re-render whenever any property of the store changes.
</Callout>

```jsx
function Example() {
  // subscribe to the whole store
  const [store, setStore] = useStore();

  return (
    <>
      <button
        onClick={() =>
          setStore((s) => ({
            ...s,
            username: 'Lando',
          }))
        }
      >
        Update {store.username}
      </button>
      <button
        onClick={() =>
          setStore((s) => ({
            ...s,
            cart: { ...s.cart, price: s.cart.price + 1 },
          }))
        }
      >
        Increment price: 💵 {store.cart.price}
      </button>
    </>
  );
}
```

### Input Parameters

| name                  | type       | description                                                                                                                                                                                                                                    | example                                                                                                                                                                                                     |
| --------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Initial value         | `any`      | This parameter is **not mandatory**. It only makes sense for new store properties that have not been defined before within the `createStore`. If the value has already been initialized inside the `createStore` this parameter has no effect. | `const [price, setPrice] = useStore.cart.price(0)`                                                                                                                                                         |
| event after an update | `function` | This parameter is **not mandatory**. Adds an event that is executed every time there is a change inside the indicated store portion.                                                                                                           | `const [price, setPrice] = useStore.cart.price(0, onAfterUpdate)`<div><small>And the function:</small></div><div>`function onAfterUpdate({ store, prevStore }){ console.log({ store, prevStore }) }`</div> |

### Return Value

Is an `Array` with **2** items:

| name         | type       | description                                                                             | example                                                                                                                                                                                                                                                                                                                                                                 |
| ------------ | ---------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| value        | `any`      | The value of the store portion indicated with the proxy.                                | A store portion <div>`const [price] = useStore.cart.price()`</div>All store: <div> `const [store] = useStore()`</div>                                                                                                                                                                                                                                                   |
| update value | `function` | Function to update the store property indicated with the proxy.                         | Updating a store portion:<div>`const [count, setCount] = useStore.count(0)`</div>Way 1:<div>`setCount(count + 1)`</div>Way 1:<div>`setCount(c => c + 1)`</div><div>-------</div>Updating all store:<div>`const [store, updateStore] = useStore()`</div>Way 1:<div>`updateStore({ ...store, count: 2 }))`</div>Way 1:<div>`updateStore(s => ({ ...s, count: 2 }))`</div> |

<FeedbackRating />
